#ifndef MAIN_H
#define MAIN_H

#include <GL/glew.h>
#include <CL/cl_gl.h>

#define __CL_ENABLE_EXCEPTIONS
#define __NO_STD_VECTOR
#include <CL/cl.hpp>

#include "Body.h"
#include "Particle.h"
#include "Timer.h"
#include "Grid.h"

int windowWidth = 1024;
int windowHeight = 768;

int oldMouseX;
int oldMouseY;
bool leftButtonPressed = false;
bool rightButtonPressed = false;

/* Changing the values here alters the initial camera view */
float rotateX = 20.0f;
float rotateY = -45.0f;
float translateZ = -30.0f;
float translateY = -5.0f;

int totalNumberOfBodies;
Body** bodies;
int totalNumberOfParticles;
Particle** particles;

Timer* timer;

//Simulation parameters
float worldSize = 15.0f; //Half length of world
float springCoefficient = 100.0f;
float dampingCoefficient = 0.5f;
float timeDelta = 0.01f;
float particleRadius = 0.20;
float terminalVelocity = 20.0f;

bool onlyDrawParticles = false;
GLfloat ground[4][3] = { /* Ground plane vertex positions */
	{ -worldSize, 0.0, -worldSize }, { -worldSize, 0.0, worldSize },
	{ worldSize, 0.0, worldSize }, { worldSize, 0.0, -worldSize } };
GLfloat groundNormal[3] = { 0.0, 1.0, 0.0 };


//Grid data structures
int* indexGrid;
int* countGrid;
float voxelSize;
int particlesPerVoxel = 4;
float gridMinimumPosition;
int gridLength;
int gridSize;

//VBO data structures
GLuint bodyVBO;
GLuint particleVBO;
int vertexCount;
cl_float* vertexData;
cl_float* normalData;
cl_float* colorData;
cl_float* particleVertexData;
cl_float* particleColorData;

//OpenCL data structures
cl_float* clBodyMass;
cl_float3* clBodyForce;
cl_float3* clBodyPosition;
cl_float3* clBodyVelocity;
cl_float3* clBodyLinearMomentum;
cl_float4* clBodyQuaternion;
cl_float* clBodyRotationMatrix;
cl_float3* clBodyAngularVelocity;
cl_float3* clBodyAngularMomentum;
cl_float3* clInitialIITDiagonal; //Initial Inverse Inertia Tensor Diagonal
cl_float* clBodyInverseInertiaTensor;

cl_float* clParticleMass;
cl_float3* clParticlePosition;
cl_float3* clParticleVelocity;
cl_float3* clParticleForce;



//Function declarations
void mouseFunc(int button, int state, int x, int y);
void resetSimulation1();
void resetSimulation2(int towerSize);
void motionFunc(int x, int y);
void keyboardFunc(unsigned char key, int x, int y);
void stepSimulation(float delta);
void drawGroundPlane();
void reshapeFunc(int w, int h);
void drawParticles();
void drawBodies();
void display();
void initGL();
void initSimulation();

#endif
